package com.itfreer.print;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.util.HashMap;

import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.codec.Base64;
import com.itextpdf.tool.xml.XMLWorker;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.itextpdf.tool.xml.html.Tags;
import com.itextpdf.tool.xml.parser.XMLParser;
import com.itextpdf.tool.xml.pipeline.css.CSSResolver;
import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline;
import com.itextpdf.tool.xml.pipeline.end.PdfWriterPipeline;
import com.itextpdf.tool.xml.pipeline.html.AbstractImageProvider;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
import com.itfreer.utils.json.JsonUtils;

import freemarker.template.Configuration;
import freemarker.template.Template;

/**
 * 发布rest调用服务
 */
@Component
@Path("/print/")
public class UserPrintRotate {

	@Autowired(required = false)
	private TemplateFilePara templateFilePara;
	
	/**
	 * 基于模板输出excel文件
	 * 
	 * @param template
	 *            模板文件
	 * @param data
	 *            模板数据
	 */
	@SuppressWarnings("rawtypes")
	@POST
	@Path("/HtmlImagesRotateToPdf")
	public Response toPdf(@FormParam("template") String template, 
			@FormParam("data") String dataString,
			@FormParam("filename") String filename) throws Exception {
		HashMap data = JsonUtils.toBean(dataString, HashMap.class);
		// 读取目标文件，通过response将目标文件写到客户端
		ByteArrayOutputStream outFile = new ByteArrayOutputStream();
		toPdf(template, data, outFile);
		//htmlToPdf.toPdf(template, data, outFile);
		StreamingOutput stream = new StreamingOutput() {
			@Override
			public void write(OutputStream output) throws IOException, WebApplicationException {
				try {
					output.write(outFile.toByteArray());
	            } catch (Exception e) {
	                throw new WebApplicationException(e);
	            }
			}
	    };
	    outFile.close();

	    return Response.ok(stream)
	    		.header("Content-Disposition","inline; filename =" + new String(filename.getBytes("utf-8"), "ISO-8859-1"))
	    		.header("Content-Type", "application/pdf")
	    		.header("Cache-Control", "no-cache").build();
	}
	
	public void toPdf(String templateFile,Object data,OutputStream os) {
		
		//String tempPath="D:\\print\\input\\test";
		
		String tempPath = templateFilePara.getTemplatePath();
		if(!tempPath.contains(":\\") && !tempPath.startsWith("/")) {
			tempPath = this.getClass().getResource("/").getPath() + tempPath;
		}
		//String templateFile="index.html";
		//Object data=null;
		 
		String html="";
		
		ByteArrayOutputStream htmlOut = new ByteArrayOutputStream();
		OutputStreamWriter htmlWriter = new OutputStreamWriter(htmlOut, Charset.forName("UTF-8"));
		
		

		try {
			Configuration freeMarkerconfig = new Configuration();
			freeMarkerconfig.setDirectoryForTemplateLoading(new File(tempPath));
			freeMarkerconfig.setDefaultEncoding("UTF-8");
			Template freeMarkerTemplateerconfig;
			freeMarkerTemplateerconfig = freeMarkerconfig.getTemplate(templateFile, "UTF-8");
			// 往模板中写入数据
			freeMarkerTemplateerconfig.process(data, htmlWriter);
			htmlWriter.flush();
			htmlOut.flush();
			
			//html=htmlOut.toString();
			
			html=new String(htmlOut.toByteArray(), "UTF-8");
			
			//OutputStream os = new FileOutputStream("D:\\print\\input\\test\\test.pdf"); 
			
			createPdf(html,os);
			
		} catch (Exception e) {
			e.printStackTrace();
			
		} 
	}

	public static void createPdf(String fileContent,OutputStream os) throws IOException, DocumentException {
		Rectangle rectPageSize = new Rectangle(PageSize.A4.rotate());// A4纸张 PageSize.A4.rotate() 横向
	    // step 1
	    Document document = new Document(rectPageSize, 36, 36, 36, 36);
	    // step 2
	    PdfWriter writer = PdfWriter.getInstance(document, os);
	    writer.setPdfVersion(PdfWriter.PDF_VERSION_1_7);
	    // step 3
	    document.open();
	    // step 4
	    // CSS
	    CSSResolver cssResolver = XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
	
	    // HTML
	    HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
	    htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
	    htmlContext.setImageProvider(new AbstractImageProvider() {
	        @Override
	        public Image retrieve(String src) {
	        	if(src==null || "".equals(src) || src.startsWith("{")|| src.startsWith("$")) {
	        		return null;
	        	}
	            int pos = src.indexOf("base64,");
	            try {
	                if (src.startsWith("data") && pos > 0) {
	                    byte[] img = Base64.decode(src.substring(pos + 7));
	                    return Image.getInstance(img);
	                } else if (src.startsWith("http")) {
	                	
	                	Image img=Image.getInstance(src);
	                	//Float width=img.getWidth();
	                	//Float heigth=img.getHeight();
	                	//img.setWidthPercentage(30f);
	                    return img;
	                } 
	            } catch (BadElementException ex) {
	                return null;
	            } catch (IOException ex) {
	                return null;
	            }
	            return null;
	        }
	        @Override
	        public String getImageRootPath() {
	            return null;
	        }
	    });
	
	    // Pipelines
	    PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
	    HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
	    CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
	
	    // XML Worker
	    XMLWorker worker = new XMLWorker(css, true);
	    XMLParser p = new XMLParser(worker);
	    p.parse(new StringReader(fileContent));
	    document.close();
	}

}
